﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.IO;
using System.Diagnostics;
using System.Reflection;
using FCS.Communication;

namespace FCS.Kiosk
{
    public partial class MainWindow : Window
    {
        String _enteredCode = "";
        String _shutdownCode; // shuts down the application
        String _lockCode; // locks or unlocks the kiosk
        EventLogWriter _writer = new EventLogWriter("Kiosk");
        bool _isLocked = false;
        System.Timers.Timer _timeToReturnToControlTab = new System.Timers.Timer(45000);

        public MainWindow()
        {
            InitializeComponent();

            _timeToReturnToControlTab.Elapsed += new System.Timers.ElapsedEventHandler(_timeToReturnToControlTab_Elapsed);

            // Hide the cursor if on a kiosk
            if (Environment.MachineName.ToLower() == "enlight-kiosk")
                this.Cursor = Cursors.None;

            // Let's also attach a event handler to catch crashes
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
            ReadCodes();

            buildLabel.Content = "Build Date: " + DateTime.Today.Date.Month + "/" + DateTime.Today.Date.Day + "/" + DateTime.Today.Year;
        }

        private delegate void MethodDelegate();
        void _timeToReturnToControlTab_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Dispatcher.Invoke(new MethodDelegate(delegate()
            {
                Tabs.SelectedIndex = 0;
            }));
        }

        private void ReadCodes()
        {
            try
            {
                using (StreamReader sr = new StreamReader(@"C:\FountainData\kioskAdminCodes.txt"))
                {
                    _shutdownCode = sr.ReadLine();
                    _lockCode = sr.ReadLine();
                }
            }
            catch (Exception)
            {
                _writer.WriteToLog(EventLogEntryType.Error, "There was an error in the admin codes file");
            }
        }

        /// <summary>
        /// Attempt to send out for help when an exception occurs
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception exception = (Exception)e.ExceptionObject;
            string message;

            message = "Exception at " + DateTime.Now.ToString() + "\n";
            message += exception.Message + "\n\n";
            message += exception.StackTrace + "\n\n\n";
            if (exception.InnerException != null)
            {
                message += exception.InnerException.Message + "\n\n";
                message += exception.InnerException.StackTrace;
            }

            // Let's write out a log
            using (StreamWriter writer = new StreamWriter(@"KioskException.log", true))
            {
                writer.WriteLine(message);
            }

            // Email for help
            EmailModule.SendStatusEmail("Help! The Kiosk is down!", "Help!\nI'm shutdown unexpectedly! Please have someone come over and turn me back on!\n\nGEEKY DETAILS:\n" + message);

            // And now we'll restart
            Process.Start(Assembly.GetEntryAssembly().FullName);
            Environment.Exit(1);
        }

        /// <summary>
        /// Make sure that the web page is always the home page
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Tabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            TabItem item = (TabItem)Tabs.SelectedItem;
            _timeToReturnToControlTab.Start();

            if (item == WebsiteTab)
                WebsiteBrowser.Navigate(new Uri("http://enlight.engr.wisc.edu/maquina/"));
        }

        /// <summary>
        /// When a hyperlink is clicked, send them to the web site tab
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WebsiteHyperlink_Click(object sender, RoutedEventArgs e)
        {
            Tabs.SelectedItem = WebsiteTab;
        }

        /// <summary>
        /// Make sure that the browser is only sent to the enlight website and it's pages ONLY
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WebsiteBrowser_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
        {
            string domain = e.Uri.Host;
            string[] validDomains = new string[] { "enlight.engr.wisc.edu" };

            if (!validDomains.Contains(domain))
                e.Cancel = true;
        }

        /// <summary>
        /// Clear out the admin code
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ClearCodeButton_Click(object sender, RoutedEventArgs e)
        {
            _enteredCode = "";
        }

        /// <summary>
        /// When the admin code is submited, check to see if it is correct for either locking the fountain control
        /// or shutting down the application
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SubmitCodeButton_Click(object sender, RoutedEventArgs e)
        {
            if (_enteredCode.Equals(_lockCode))
            {
                if (_isLocked)
                    ControlTab.IsEnabled = true;
                else
                    ControlTab.IsEnabled = false;
                _isLocked = !_isLocked;
            }
            else if (_enteredCode.Equals(_shutdownCode))
                Application.Current.Shutdown();

            _enteredCode = "";
        }

        /// <summary>
        /// When a number is pressed on the admin screen, add it to the code
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NumberButton_Click(object sender, RoutedEventArgs e)
        {
            _enteredCode += ((Button)sender).Content;
        }
    }
}
